package com.example.schoolguider.util;

import com.alibaba.fastjson.JSON;
import com.example.schoolguider.model.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author wjc
 * @date 2023/11/8 16:56
 */
@Service
public class JWTUtil {
    //签名私钥
    @Value("${jwt.config.key}")
    private String key;
    private static String KEY;
    //签名有效时间
    @Value("${jwt.config.timeOut}")
    private Long timeout;
    private static Long TIMEOUT;

    @PostConstruct
    public void init() {
        KEY = this.key;
        TIMEOUT = this.timeout;
    }

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public Long getTimeOut() {
        return TIMEOUT;
    }
    public void setTimeOut(Long timeOut) {
        this.TIMEOUT = timeOut;
    }

    /**
     * 设置认证token
     *      id:用户id
     *      subject:用户名
     */
    public static String createJwt(String id, String name, Map<String,Object> map) {
        //1.设置失效时间
        long nowTime = System.currentTimeMillis();//当前毫秒
        long expirationTime = nowTime + TIMEOUT;
        //2.创建jwtBuilder
        JwtBuilder jwtBuilder = Jwts.builder();
        //3.根据map设置claims
        //当设置的是整个map时，就需放在最前面，下面的setId等参数才会有效，否则会把前面set的值置空
        jwtBuilder.setClaims(map);
        jwtBuilder.setId(id);
        jwtBuilder.setSubject(name);
        jwtBuilder.setIssuedAt(new Date());//设置当前时间
        jwtBuilder.signWith(SignatureAlgorithm.HS256, KEY);//设置加密方式
        jwtBuilder.setExpiration(new Date(expirationTime));//设置过期时间
        //4.创建token
        String token = jwtBuilder.compact();
        return token;
    }
    public static String createJwt(User user) {
        //1.设置失效时间
        long nowTime = System.currentTimeMillis();//当前毫秒
        long expirationTime = nowTime + TIMEOUT;
        //2.创建jwtBuilder
        JwtBuilder jwtBuilder = Jwts.builder();
        //3.根据map设置claims
        //当设置的是整个map时，就需放在最前面，下面的setId等参数才会有效，否则会把前面set的值置空
        Map map = new HashMap();
        map.put("user",user);
        jwtBuilder.setClaims(map);

        jwtBuilder.setIssuedAt(new Date());//设置当前时间
        jwtBuilder.signWith(SignatureAlgorithm.HS256, KEY);//设置加密方式
        jwtBuilder.setExpiration(new Date(expirationTime));//设置过期时间
        //4.创建token
        String token = jwtBuilder.compact();
        return token;
    }

    public static User getUser(String token){

        Claims claims = parseJwt(token);
        return JSON.parseObject(JSON.toJSONString(claims.get("user", LinkedHashMap.class)),User.class);
    }
    /**
     * 解析token字符串获取clamis
     */
    public static Claims parseJwt(String token) {
        Claims claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
        return claims;
    }

}

